#include "liolib/lioflat.h"

#define LINE 16
#define HEIGHT 20
#define SIDE 35


typedef struct _FONT_INFO
{
	LOGFONT lf;
	TEXTMETRIC tm;
	DWORD type;
	Font font;
} FontInfo;

class FontManager:public FlatApplication
{
protected:
	
	List<FontInfo> fontInfos;
	typedef List<FontInfo>::Object FontObject;
	int fontCount,index;
	Font fontSmall,*fontSelect;
	FontInfo *fontInfo;
	String fontFace;
	FlatSelect list;
	BOOL create();
	BOOL glCreate();
	void glDestroy();
	void destroy();
	void reshape ();
	BOOL listen(WORD id, WORD code, const void *info);
	void draw2D();
	void action();
	int addFont(CONST LOGFONT *lplf, CONST TEXTMETRIC *lptm, DWORD dwType);
	static int CALLBACK fontEnumProc(
							CONST LOGFONT *lplf,     // logical-font data
							CONST TEXTMETRIC *lptm,  // physical-font data
							DWORD dwType,            // font type
							LPARAM lpData);          // application-defined data
} fm;
int CALLBACK FontManager::fontEnumProc(
							CONST LOGFONT *lplf,     // logical-font data
							CONST TEXTMETRIC *lptm,  // physical-font data
							DWORD dwType,            // font type
							LPARAM lpData)           // application-defined data
{
	return ((FontManager*)lpData)->addFont(lplf,lptm,dwType);
}
int FontManager::addFont(CONST LOGFONT *lplf, CONST TEXTMETRIC *lptm, DWORD dwType)
{
	FontInfo *fontInfo=fontInfos.add();
	if(fontInfo)
	{
		memcpy(&(fontInfo->lf),lplf,sizeof(LOGFONT));
		memcpy(&(fontInfo->tm),lptm,sizeof(TEXTMETRIC));
		fontInfo->type=dwType;
		fontCount++;
		DynamicString str=format.toString(fontCount,_T("%03d"));
		str+=_T(". ");
		str+=lplf->lfFaceName;
		if(list.add(str.toString()))
		{
			container.build();
			list.setSelectedIndex(fontCount-1);
			list.scroll.increase();
			fontInfo->font.setFace(fontInfo->lf.lfFaceName);
			fontInfo->font.height=-HEIGHT;
			fontInfo->font.charset=fontInfo->tm.tmCharSet;
			fontInfo->font.first=fontInfo->tm.tmFirstChar;
			fontInfo->font.count=fontInfo->tm.tmLastChar-fontInfo->tm.tmFirstChar+1;
			fontInfo->font.create(window.hDC);
			fontInfo->font.color=INT_BLACK;
			action();
			redraw();
			return 1;
		}
	}
	return 0;
}
BOOL FontManager::create ()				
{
	FlatApplication::create();
	name=_T("FontManager");
	display.width=1024;
	display.height=768;
	display.bpp=32;
	clearColor=INT_WHITE;
	index=-1;
	fontInfo=NULL;

	fontSmall.setFace(_T("Courier New"));
	fontSmall.height=-12;
	font.color=fontSmall.color=INT_BLACK;

	list.location.set(10,30);
	list.adjustSize=TRUE;
	list.margin.set(5,5);
	list.readLines=40;
	list.fontColor=INT_DGRAY;
	list.bgColor=INT_WHITE;
	list.borderColor=INT_BLACK;
	add(&list);

	return TRUE;
}
BOOL FontManager::glCreate ()
{
	FlatApplication::glCreate();
	fontSmall.create(window.hDC);
	fontCount=0;
	EnumFonts(window.hDC,NULL,fontEnumProc,(LPARAM)this);
	return TRUE;
}
void FontManager::glDestroy()
{
	fontSmall.destroy();
	FlatApplication::glDestroy();
}
void FontManager::destroy()
{
	FlatApplication::destroy();
}
void FontManager::reshape()
{
	FlatApplication::reshape();
}
void FontManager::action()
{
	index=list.getSelectedIndex();
	if(index>=0)
	{
		FontObject fo=fontInfos.objectAt(index);
		fontInfo=&(fo->value);
		fontSelect=&(fontInfo->font);
	}
}
BOOL FontManager::listen(WORD id, WORD code, const void *info)
{
	if(id==list.id)
	{
		if(code==FLAT_ACTION_DEFAULT)
		{
			action();
			return TRUE;
		}
	}
	return FALSE;
}
void FontManager::draw2D()
{
	int i;
	double x,y;
	font.x=10;
	font.y=20;
	glPrint(&font,_T("Font count: %d"),fontCount);
	if(fontInfo)
	{
		fontSmall.color=INT_DGRAY;
		font.x=fontSmall.x=list.getRect().right()+20;
		fontSmall.y=40;
		glPrint(&font,_T("Font info:"));
		glPrint(&fontSmall,_T("Height:    %d"),fontInfo->tm.tmHeight);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("Ascent:    %d"),fontInfo->tm.tmAscent);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("Descent:   %d"),fontInfo->tm.tmDescent);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("IntLead:   %d"),fontInfo->tm.tmInternalLeading);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("ExtLead:   %d"),fontInfo->tm.tmExternalLeading);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("AveWidth:  %d"),fontInfo->tm.tmAveCharWidth);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("MaxWidth:  %d"),fontInfo->tm.tmMaxCharWidth);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("Weight:    %d"),fontInfo->tm.tmWeight);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("Overhang:  %d"),fontInfo->tm.tmOverhang);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("AspectX:   %d"),fontInfo->tm.tmDigitizedAspectX);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("AspectY:   %d"),fontInfo->tm.tmDigitizedAspectY);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("FirstChar: %d"),fontInfo->tm.tmFirstChar);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("LastChar:  %d"),fontInfo->tm.tmLastChar);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("DefChar:   %d"),fontInfo->tm.tmDefaultChar);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("BreakChar: %d"),fontInfo->tm.tmBreakChar);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("Italic:    %d"),fontInfo->tm.tmItalic);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("Underline: %d"),fontInfo->tm.tmUnderlined);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("StruckOut: %d"),fontInfo->tm.tmStruckOut);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("Family:    %d"),(0xf0&fontInfo->tm.tmPitchAndFamily)>>4);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("VarPitch:  %d"),(TMPF_FIXED_PITCH&fontInfo->tm.tmPitchAndFamily)!=0);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("Vector:    %d"),(TMPF_VECTOR&fontInfo->tm.tmPitchAndFamily)!=0);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("TrueType:  %d"),(TMPF_TRUETYPE&fontInfo->tm.tmPitchAndFamily)!=0);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("Device:    %d"),(TMPF_DEVICE&fontInfo->tm.tmPitchAndFamily)!=0);
		fontSmall.y+=LINE;
		glPrint(&fontSmall,_T("CharSet:   %d"),fontInfo->tm.tmCharSet);

		x=font.x+=130;
		y=25;
		glPrint(&font,_T("Font chars:"));

		setColor(INT_BLACK);
		glBegin(GL_LINES);
		for (i = 0; i<16; i++)
		{
			glVertex2d(x+(i-0.25)*SIDE,y+0.25*SIDE);
			glVertex2d(x+(i-0.25)*SIDE,y+0.25*SIDE+18*SIDE);
		}
		for (i = 0; i<19; i++)
		{
			glVertex2d(x-0.25*SIDE,y+(i+0.25)*SIDE);
			glVertex2d(x-0.25*SIDE+15*SIDE,y+(i+0.25)*SIDE);
		}
		glEnd();

		fontSmall.color=INT_BLUE;
		for(i=0;i<fontSelect->first+fontSelect->count;i++)
		{
			fontSmall.x=(fontSelect->x=x+(i%15)*SIDE)-0.25*SIDE+1;
			fontSmall.y=(fontSelect->y=y+SIDE+(i/15)*SIDE)-0.5*SIDE+1;
			if(i>=fontSelect->first)
				glPrint(fontSelect,_T("%c"),i);
			glPrint(&fontSmall,_T("%d"),i);
		}
	}
}


int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdMap)
{
	return fm.main(hInstance,hPrevInstance,lpCmdLine,nCmdMap);
}